﻿/* 
 * Copyright 2010 Justin Pealing
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace Minnow.Web.Http
{
    /// <summary>
    /// Describes an incoming HTTP request.
    /// </summary>
    public interface IHttpRequest
    {
        /// <summary>
        /// Gets the MIME types accepted by the client, or null if the client request did
        /// not include an Accept header.
        /// </summary>
        string[] AcceptTypes { get; }

        /// <summary>
        /// Gets an error code that identifies a problem with the <see cref="System.Security.Cryptography.X509Certificates.X509Certificate" />
        /// provided by the client
        /// </summary>
        int ClientCertificateError { get; }

        /// <summary>
        /// Gets the content encoding suitable for use with the data sent with the request
        /// </summary>
        Encoding ContentEncoding { get; }

        /// <summary>
        /// Gets the length of the body data included in the request, or -1 if the content length
        /// is not know.
        /// </summary>
        long ContentLength { get; }

        /// <summary>
        /// Gets the value of the request's Content-Type header.
        /// </summary>
        string ContentType { get; }

        /// <summary>
        /// Gets the cookies sent with the request.
        /// </summary>
        /// <remarks>
        /// This property returns an empty collection if the request does not contain any cookies.
        /// </remarks>
        CookieCollection Cookies { get; }

        /// <summary>
        /// True if the request has associated body data; otherwise, false.
        /// </summary>
        bool HasEntityBody { get; }

        /// <summary>
        /// Gets the collection of header name/value pairs sent in the request.
        /// </summary>
        NameValueCollection Headers { get; }

        /// <summary>
        /// Gets the HTTP method specified by the client.
        /// </summary>
        string HttpMethod { get; }

        /// <summary>
        /// Gets a stream that contains the body data sent by the client.
        /// </summary>
        /// <remarks>
        /// This property returns <see cref="System.IO.Stream.Null" /> if no data is sent with 
        /// the request.
        /// </remarks>
        Stream InputStream { get; }

        /// <summary>
        /// True if the client sending this request is authenticated; otherwise, false.
        /// </summary>
        bool IsAuthenticated { get; }

        /// <summary>
        /// True if the request originated on the same computer as the source object that provided
        /// the request; otherwise, false.
        /// </summary>
        bool IsLocal { get; }

        /// <summary>
        /// True if the TCP connection is the Secure Sockets Layer (SSL) protocol; otherwise, false.
        /// </summary>
        bool IsSecureConnection { get; }

        /// <summary>
        /// True if the client requests a persistent connection; otherwise, false.
        /// </summary>
        bool KeepAlive { get; }

        /// <summary>
        /// Get the server IP address and port number to which the request is directed.
        /// </summary>
        IPEndPoint LocalEndPoint { get; }

        /// <summary>
        /// Gets the HTTP version used by the requesting client.
        /// </summary>
        Version ProtocolVersion { get; }

        /// <summary>
        /// Gets the query string included in the request.
        /// </summary>
        NameValueCollection QueryString { get; }

        /// <summary>
        /// Gets the URL information (without the host and port) requested by the client.
        /// </summary>
        string RawUrl { get; }

        /// <summary>
        /// Gets the client IP address and port number from which the request originated.
        /// </summary>
        IPEndPoint RemoteEndPoint { get; }

        /// <summary>
        /// Gets the request identifier of the incoming HTTP request.
        /// </summary>
        Guid RequestTraceIdentifier { get; }

        /// <summary>
        /// Gets the <see cref="System.Uri" /> object requested by the client.
        /// </summary>
        Uri Url { get; }

        /// <summary>
        /// Gets the Uniform Resource Identifier (URI) of the resource that referred
        /// the client to the server.
        /// </summary>
        Uri UrlReferrer { get; }

        /// <summary>
        /// Gets the user agent presented by the client.
        /// </summary>
        string UserAgent { get; }

        /// <summary>
        /// Gets the server IP address and port number to which the request is directed.
        /// </summary>
        string UserHostAddress { get; }

        /// <summary>
        /// Gets the DNS name and, if provided, the port number specified by the client.
        /// </summary>
        string UserHostName { get; }

        /// <summary>
        /// Gets the natural languages that are preferred for the response.
        /// </summary>
        /// <remarks>
        /// This property returns null if the client request did not include an Accept-Language
        /// header.
        /// </remarks>
        string[] UserLanguages { get; }

        /// <summary>
        /// Begins an asynchronous request for the client's X.509 v.3 certificate.
        /// </summary>
        /// <param name="RequestCallback">An <see cref="System.AsyncCallback" /> delegate that references 
        /// the method to invoke when the operation is complete.</param>
        /// <param name="state">A user-defined object that contains information about the operation. This
        /// object is passed to the callback delegate when the operation completes.</param>
        /// <returns>An System.IAsyncResult that indicates the status of the operation.</returns>
        IAsyncResult BeginGetClientCertificate(AsyncCallback RequestCallback, object State);

        /// <summary>
        /// Ends an asynchronous request for the client's X.509 v.3 certificate.
        /// </summary>
        /// <param name="AsyncResult">The pending request for the certificate.</param>
        /// <returns>The System.IAsyncResult object that is returned when the operation started.</returns>
        /// <exception cref="System.ArgumentNullException">AsyncResult is null.</exception>
        X509Certificate2 EndGetClientCertificate(IAsyncResult AsyncResult);

        /// <summary>
        /// Retrieves the client's X.509 v.3 certificate.
        /// </summary>
        /// <returns>A <see cref="System.Security.Cryptography.X509Certificates" /> object that contains the
        /// client's X.509 v.3 certificate.</returns>
        /// <exception cref="System.InvalidOperationException">A call to this method to retrieve the client's X.509 
        /// v.3 certificate is in progress and therefore another call to this method cannot be made.</exception>
        X509Certificate2 GetClientCertificate(); 
    }
}
